import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ObjectInputStream.GetField;
import java.util.LinkedList;
//import java.util.Timer;
//import java.util.TimerTask;

import javax.swing.*;

public class ToDo implements ActionListener {
	 static LinkedList<Flight> FlightList = new LinkedList<Flight>();
	Boolean flag = false;
	public static Timer timer;
	static LinkedList<PassportUnit> PUList = new LinkedList<PassportUnit>();
	static LinkedList<BaggageCarousel> baggageList = new LinkedList<BaggageCarousel>();
	public static  LinkedList<CustomUnit> customsList = new LinkedList<CustomUnit>();
	class ThreadClass extends Thread {
		int id;

		public ThreadClass(int id) {
			this.id = id;
		}

		public void run() {

			while (flag = true) {

				if (PUList.get(this.id - 1).queue.size() == 0) {
					try {
						synchronized (this) {

							this.wait();

						}
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

				try {

					synchronized (this) {

						Passenger p = PUList.get(this.id - 1).queue.remove(0);
						for (int i = 0; i < baggageList.size(); i++) {
							if (baggageList.get(i).flightName
									.equalsIgnoreCase(p.flight.Inbound)) {
								BaggageCarousel bg = baggageList.get(i);
								bg.passengerList.add(p);

								synchronized (this) {
									if(!bg.isAlive())
									bg.notify();

								}
								System.out.println("Baggage Carousel with ID "
										+ baggageList.get(i).id
										+ " serves "
										+ baggageList.get(i).passengerList
												.size() + " Passenger");
								break;
							}
						}

						this.wait(2000);

					}
					synchronized (this) {

						this.notify();

					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}

		}
	}

	/*
	 * firststage method input Flight
	 */
	public void firststage(Flight flight) {

		// find the passport unit with the minimum queue
		Passenger p;
		PassportUnit pu;
		int counter = flight.paxList.size();
		for (int i = 0; i < counter; i++) {
			// System.out.println(flight.paxList.size());
			pu = getMin(PUList);
			p = flight.paxList.remove(0);
			pu.queue.add(p);

		}
		for (int i = 0; i < PUList.size(); i++) {
			System.out.println("passenger unit with id " + PUList.get(i).id
					+ " has queue of length " + PUList.get(i).queue.size());
		}
		passportProcess(PUList);

	}

	/*
	 * getMin method
	 */

	public PassportUnit getMin(LinkedList<PassportUnit> list) {
		PassportUnit pumin;
		pumin = list.get(0);
		// System.out.println("a");
		for (int i = 0; i < list.size(); i++) {

			if (list.get(i).queue.size() <= pumin.queue.size()) {
				// System.out.println("a");
				pumin = list.get(i);
			}
		}
		// System.out.println(pumin.id);

		return pumin;

	}

	/*
	 * passportProcess Method
	 */
	public void passportProcess(LinkedList<PassportUnit> list) {

		for (int i = 0; i < list.size(); i++) {
			ThreadClass th = new ThreadClass(list.get(i).id);

			if (list.get(i).queue.size() > 0) {

				th.start();

			}

		}
	}

	public static void getMinBaggageFree(Flight flight) {
		BaggageCarousel baggage = null;
		LinkedList<BaggageCarousel> temp = new LinkedList<BaggageCarousel>();
		for (int i = 0; i < baggageList.size(); i++)
			if (!baggageList.get(i).busy)
				temp.add(baggageList.get(i));
		for (int i = 0; i < temp.size(); i++)
			if (temp.get(i).capacity < Math.ceil(flight.PaxIn * 2.5))
				temp.remove(i);

		baggage = temp.get(0);

		for (int i = 0; i < temp.size(); i++) {

			if (temp.get(i).capacity <= baggage.capacity)
				baggage = temp.get(i);

		}
		baggage.flightName = flight.Inbound;
		baggage.currentNumber = (int) Math.ceil(flight.paxList.size() * 2.5);
		baggage.busy = true;
		baggage.start();
		System.out.println("Baggage Number " + baggage.id + " serves flight "
				+ flight.Inbound);

	}

	public static void getMinBaggageBusy(Flight flight) {
		BaggageCarousel b = null;
		for (int i = 0; i < baggageList.size(); i++) {
			if (baggageList.get(i).capacity - baggageList.get(i).currentNumber > Math
					.ceil(flight.PaxIn * 2.5)) {
				b = baggageList.get(i);
				b.flightName = flight.Inbound;
				b.currentNumber = (int) Math.ceil(flight.paxList.size() * 2.5);
				b.busy = true;
				b.start();
				System.out.println(b.isAlive());

				break;
			}
		}
		System.out.println("Baggage number " + b.id + " serves flight "
				+ b.flightName);

	}

	public static void assignBaggage(Flight flight) {
		for (int i = 0; i < baggageList.size(); i++)
			if (!baggageList.get(i).busy) {
				getMinBaggageFree(flight);
				break;
			} else
				getMinBaggageBusy(flight);

	}

	public static void main(String args[]) {

		System.out.println("Program Start !");
		System.out.println("Waiting.");

		LinkedList<Passenger> queueList1 = new LinkedList<Passenger>();
		LinkedList<Passenger> queueList2 = new LinkedList<Passenger>();
		LinkedList<Passenger> queueList3 = new LinkedList<Passenger>();
		LinkedList<Passenger> queueList4 = new LinkedList<Passenger>();
		LinkedList<Passenger> queueList5 = new LinkedList<Passenger>();
		LinkedList<Passenger> queueList6 = new LinkedList<Passenger>();
		
		CustomUnit C1 = new CustomUnit(1,5000);
		CustomUnit C2 = new CustomUnit(2,5000);
		CustomUnit C3 = new CustomUnit(3,5000);
		customsList.add(C1);
		customsList.add(C2);
		customsList.add(C3);
		
		
		BaggageCarousel b1 = new BaggageCarousel(1, 100,1000);
		BaggageCarousel b2 = new BaggageCarousel(2, 300,1000);
		BaggageCarousel b3 = new BaggageCarousel(3, 200,1000);
		baggageList.add(b1);
		baggageList.add(b2);
		baggageList.add(b3);


		PassportUnit pu1 = new PassportUnit(1,3);
		PassportUnit pu2 = new PassportUnit(2,2);
		PassportUnit pu3 = new PassportUnit(3,3);
		PUList.add(pu1);
		PUList.add(pu2);
		PUList.add(pu3);
		
		
		// Flight f3 = new Flight("flight 3", 100, 7);
	


		ToDo todo = new ToDo();
		JFrame frame = new JFrame("FrameDemo");
		frame.setVisible(true);
		
		timer = new Timer(FlightList.get(0).date * 1000, todo);
		FlightList.get(0).isarrived = true;

		for (int i = 1; i < FlightList.size(); i++) {
			timer.setDelay(FlightList.get(i).date * 1000);
			FlightList.get(i).isarrived = true;

		}

		timer.start();
		frame.setVisible(false);

	}

	int i = 0;

	@Override
	public void actionPerformed(ActionEvent e) {

		if (i < FlightList.size()) {
			if (FlightList.get(i).isarrived) {
				System.out.println("Flight " + FlightList.get(i).Inbound
						+ " arrived");
				firststage(FlightList.get(i));
				assignBaggage(FlightList.get(i));

			}
			i++;

		}

	}
}
